package pl.ydp.components.mathcell.mathcell.preprocessing
{
	import pl.ydp.components.mathcell.mathcell.preprocessing.multicharacter.MultiCharacterContainer5;

	public class ScaleAnalyzer
	{
		public static function getCharactersHeights(mcc:MultiCharacterContainer5):Array{
			var scaleDatas:Array = new Array;
			var lineCharacters:Array = new Array;
			var fc:Number;
			
			for (var c:Number = 0 ; c < mcc.charactersCount ; c ++){
				if (mcc.isFractionAt(c)){
					var fractionScaleDatas:Array = new Array;
					var numScaleVData:ScaleProjectionData = findVerticalData(mcc.getFractionNumeratorCharactersPointsAt(c));
					fractionScaleDatas.push(new Array);
					for (fc = 0 ; fc < mcc.getFractionNumeratorCharactersPointsAt(c).length ; fc++){
						var numCharScaleHData:ScaleProjectionData = findHorizontalData(mcc.getFractionNumeratorCharactersPointsAt(c)[fc]);
						fractionScaleDatas[0].push(new ScaleCharacterData(numCharScaleHData, numScaleVData));
					}
					
					var denScaleVData:ScaleProjectionData = findVerticalData(mcc.getFractionDenominatorCharactersPointsAt(c));
					fractionScaleDatas.push(new Array);
					for (fc = 0 ; fc < mcc.getFractionDenominatorCharactersPointsAt(c).length ; fc++){
						var denCharScaleHData:ScaleProjectionData = findHorizontalData(mcc.getFractionDenominatorCharactersPointsAt(c)[fc]);
						fractionScaleDatas[1].push(new ScaleCharacterData(denCharScaleHData, denScaleVData));
					}					
					
					scaleDatas.push(fractionScaleDatas);
				} else {
					lineCharacters.push(mcc.getCharacterPointsAt(c));
					scaleDatas.push(-1);
				}
			}
			
			var lineScaleVData:ScaleProjectionData = findVerticalData(lineCharacters);
			
			for (var i:Number = 0 ; i < scaleDatas.length ; i ++){
				if (scaleDatas[i] == -1){
					var characterScaleHData:ScaleProjectionData = findHorizontalData(mcc.getCharacterPointsAt(i));
					scaleDatas[i] = new ScaleCharacterData(characterScaleHData, lineScaleVData);
				}
			}
			
			return scaleDatas;
		}
		
		private static function findVerticalData(characters:Array):ScaleProjectionData{
			var min:Number = Infinity;
			var max:Number = -Infinity;
			
			for (var c:Number = 0 ; c < characters.length ; c ++){
				for (var stroke:Number = 0 ; stroke < characters[c].length ; stroke++){
					for (var p:Number = 0 ; p < characters[c][stroke].length ; p++){
						if (characters[c][stroke][p].y < min){
							min = characters[c][stroke][p].y;
						}						
						if (characters[c][stroke][p].y >  max){
							max = characters[c][stroke][p].y;
						}
					}
					
				}
			}
			
			return new ScaleProjectionData(max-min, min);
		}
		
		private static function findHorizontalData(strokes:Array):ScaleProjectionData{
			var min:Number = Infinity;
			var max:Number = -Infinity;
			
			for (var stroke:Number = 0 ; stroke < strokes.length ; stroke++){
				for (var p:Number = 0 ; p < strokes[stroke].length ; p++){
					if (strokes[stroke][p].x < min){
						min = strokes[stroke][p].x;
					}						
					if (strokes[stroke][p].x >  max){
						max = strokes[stroke][p].x;
					}
				}
				
			}
			
			return new ScaleProjectionData(max-min, min);
		}
	}
}